package model.environmentConfig;


import javax.xml.bind.annotation.*;

import java.net.*;
import java.util.*;

@XmlRootElement(name="environmentConfiguration")
@XmlAccessorType(XmlAccessType.FIELD)
public class EnvironmentConfiguration
{

	@XmlElementWrapper(name="nodes")
	@XmlElement(name="node")
	private HashMap<Long, Node> nodes;
	@XmlTransient
	private String fileName = null;
	
	@XmlElementWrapper(name="channels")
	@XmlElement(name="channel")
	private List<CommunicationChannel> channels;
	
	@XmlTransient
	private Object selectedObj;
	
	@XmlTransient
	private Node simulatingNode;

	public EnvironmentConfiguration(){
		this.nodes = new HashMap<Long, Node>();
		this.channels = new ArrayList<CommunicationChannel>();
		this.fileName = null;
	}
	
	public void detectSimulatingNode(){
		try{
			for(Node node:nodes.values()){
				if(InetAddress.getLocalHost().getHostAddress().compareTo(node.getExternalIPAddress())==0){
					this.simulatingNode=node;
					break;
				}
			}
		}
		catch(UnknownHostException e){
			//TODO: maybe something here
		}
	}
	
	public Node getSimulatingNode(){
		return(simulatingNode);
	}
	
	public void setSimulatingNode(Node node){
		this.simulatingNode=node;
	}
	
	public HashMap<Long, Node> getNodes(){
		return(nodes);
	}
	
	public void setNodes(HashMap<Long, Node> nodes){
		this.nodes=nodes;
	}
	
	public List<CommunicationChannel> getChannels(){
		return(channels);
	}
	
	public void setChannels(ArrayList<CommunicationChannel> channels){
		this.channels=channels;
	}
	
	public void addChannel(CommunicationChannel channel){
		this.channels.add(channel);
	}
	
	public void removeChannel(CommunicationChannel channel){
		this.channels.remove(channel);
	}
	
	public void addNode(Node newNode){
		Long newKey;
		Random random=new Random();
		do{
			newKey=random.nextLong();
		}while(nodes.get(newKey)!=null);
		
		nodes.put(newKey, newNode);
	}
	
	public void removeNode(Long key){
		nodes.remove(key);
	}
	
	public void setFileName(String fileName){
		this.fileName = fileName;
	}
	
	public String getFileName(){
		return fileName;
	}
	
	public Object getSelectedObj(){
		return(selectedObj);
	}
	
	public void setSelectedObj(Object selectedObj){
		this.selectedObj=selectedObj;
	}
	
	@Override
	public boolean equals(Object e){
		if(!(e instanceof EnvironmentConfiguration)){
			return(false);
		}
		
		EnvironmentConfiguration env=(EnvironmentConfiguration)e;
		
		if(this.nodes.size()!=env.getNodes().size()){
			return(false);
		}
		
		for(Long key:this.nodes.keySet()){
			if(!(this.nodes.get(key).equals(env.getNodes().get(key)))){
				return(false);
			}
		}
		
		if(!(this.channels.containsAll(env.getChannels()))){
			return(false);
		}
		
		return(true);
	}
}
